package com.ershi.spring.ioc;

import com.ershi.spring.ioc.beanFactory.MyClassPathXmlApplicationContext;
import com.ershi.spring.ioc.domain.Person;
import com.ershi.spring.ioc.domain.Women;
import com.ershi.spring.ioc.evnet.MyEvent;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;

/**
 * @author 二十
 * @since 2021/10/30 6:12 下午
 *
 * ioc容器创建和组件的所有执行逻辑的启动入口
 */
public class IocMainTest {

	private static final String CONFIG_LOCATION = "applicationContext.xml";

	public static void main(String[] args) {

		//通过上层接口打点spring ioc
		//testXmlBeanFactory();

		//自定义 ioc 容器进行扩展
		//testDiyIoc();

		//测试spring 的 ioc 容器的事件发布 & 监听
		//testPublishEvent();

		//测试三级缓存与循环依赖
		testCyclicDependence();

		//测试生命周期相关的两个类
		//testLifecycle();


	}



	/**
	 * 通过上层接口打点spring ioc
	 */
	private static void testXmlBeanFactory(){
		BeanFactory ioc = new XmlBeanFactory(new ClassPathResource(CONFIG_LOCATION));

		Person person = ioc.getBean("person", Person.class);
		System.out.println("person = " + person);
	}

	/**
	 * 自定义 ioc 容器进行扩展
	 */
	private static void testDiyIoc() {
		MyClassPathXmlApplicationContext ioc = new MyClassPathXmlApplicationContext(CONFIG_LOCATION);
		Person person = ioc.getBean("person", Person.class);
		System.out.println("person = " + person);
	}

	/**
	 * 测试spring 的 ioc 容器的事件发布
	 */
	private static void testPublishEvent() {
		ApplicationContext ioc = new ClassPathXmlApplicationContext(CONFIG_LOCATION);
		ioc.publishEvent(new MyEvent("", "这是我自定义的一个事件"));
	}

	/**
	 * 测试三级缓存与循环依赖
	 */
	private static void testCyclicDependence() {
		ApplicationContext ioc = new ClassPathXmlApplicationContext(CONFIG_LOCATION);
		Women women = ioc.getBean("women", Women.class);
		System.out.println(women);
	}

	/**
	 * 传递的参数autoStartUpOnly是干嘛的？
	 * 表示只启动SmartLifeCycle生命周期对象，并且启动的对象autoStartUpOnly必须是true，
	 * 不会启动普通的生命周期对象，
	 * false的时候，会启动全部的生命周期对象。
	 */
	private static void testLifecycle() {
		ApplicationContext ioc = new ClassPathXmlApplicationContext(CONFIG_LOCATION);
	}

}
